package org.pms.core.dao;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.pms.core.entity.Person;
import org.pms.core.exception.DataAccessException;


/**
 * Persistência da entidade Pessoa
 * 
 * @author Paulo
 *
 */
public class PersonDaoImpl implements PersonDao {
	private static Logger logger = Logger.getLogger(PersonDaoImpl.class);
	
	/**
	 * Obtem todas as pessoas
	 * @return
	 */
	@Override
	public List<Person> findAll() throws DataAccessException {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		List<Person> persons = null;
		
		try {
			persons =  session.createQuery("from Person").list();			
			tx.commit();
		} catch (Exception e) {
			logger.error("Unable to execute findAll",e);
			tx.rollback();
		    throw new DataAccessException(e);
		} finally {
			session.close();
		}
		
		return persons;
	}
	
	/**
	 * Obtem pessoa pelo seu identificador
	 * @param id identificador banco de dados
	 * @return Person - pessoa
	 */
	@Override
	public Person findById(Integer id) throws DataAccessException {	
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		Person person = null;
		
		try {		
			person = (Person) session.get(Person.class, id);
			tx.commit();
		} catch (Exception e) {
			logger.error("Unable to execute findById",e);
			tx.rollback();
		    throw new DataAccessException(e);
		} finally {
			session.close();
		}
		
		
		return person;
	}
	
	/**
	 * Salva ou atualiza os dados da pessoa
	 * @param person dados da pessoa a serem salvos
	 * @return Person pessoa com dados atualizados
	 */
	@Override
	public Person saveOrUpdate(Person person) throws DataAccessException {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		
		try {
			session.saveOrUpdate(person);
			tx.commit();
		} catch (Exception e) {
			logger.error("Unable to execute saveOrUpdate",e);
			tx.rollback();
		    throw new DataAccessException(e);
		} finally {
			session.close();
		}
		
		return person;
	}
	
	/**
	 * Salva os dados da pessoa
	 * @param person dados da pessoa a serem salvos
	 * @return Person pessoa com os dados salvos
	 */
	@Override
	public Person save(Person person) throws DataAccessException {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		
		try {
			session.save(person);
			tx.commit();
		} catch (Exception e) {
			logger.error("Unable to execute save",e);
			tx.rollback();
		    throw new DataAccessException(e);
		} finally {
			session.close();
		}
		
		return person;
	}
	
	/**
	 * Remove uma pessoa do banco de dados
	 * 
	 * @param person pessoa a ser removida do banco
	 */
	@Override
	public void delete(Person person) throws DataAccessException {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		try {
			session.delete(person);
			tx.commit();
		} catch (Exception e) {
			logger.error("Unable to execute delete",e);
			tx.rollback();
		    throw new DataAccessException(e);
		} finally {
			session.close();
		}
	}

}
